#include "SWKNXDevice.h"

SWKNXDevice::SWKNXDevice(QObject *parent) :
    BaseInterface<SWKNXDevice>(parent)
{

    qDebug()<<"this is SWKNXDevice constructor";


     m_pInstance = this;
    swKNXProtocol = new SWKNXProtocol(this);

    this->registerProtocol(swKNXProtocol);

     DelaySendList.clear();

    getStatusTimer = new QTimer(this);
   connect(getStatusTimer, SIGNAL(timeout()), this, SLOT(getStatusSlot()));

    getStatusTimer->setInterval(8*1000);
  getStatusTimer ->start();

    getMacTimer = new QTimer(this);

    connect(getMacTimer, SIGNAL(timeout()), this, SLOT(getMacSlot()));

    getMacTimer->setInterval(5*1000);
    getMacTimer ->start();

     registerCmdHandler(ackKNXMacCmd::FunctionCode,ackKNXMacCmd::staticMetaObject, &SWKNXDevice::ackKNXMacCmdHandle);
      registerCmdHandler(ackKNXStatusCmd::FunctionCode,ackKNXStatusCmd::staticMetaObject, &SWKNXDevice::ackKNXStatusCmdHandle);
      registerCmdHandler(readKNXCtrlCmd::FunctionCode,readKNXCtrlCmd::staticMetaObject, &SWKNXDevice::readKNXCtrlCmdHandle);
  //  registerFuncHandler(ControlPointFunc::FunctionCode, &SWKNXDevice::controlPointFuncHandle);
    registerFuncHandler(ControlKNXFunc::FunctionCode,&SWKNXDevice::controlKNXFuncHandle);

    DelaySendTimer = new QTimer(this);
    DelaySendTimer->setInterval(100);
    connect(DelaySendTimer, SIGNAL(timeout()), this, SLOT(DelaySendSlot()));
    DelaySendTimer->start();

    //connect(this,SIGNAL(SignalWriteC3()),this,SLOT(writeC3()));



}
void SWKNXDevice::writeFB(quint16 address,quint8 len,QByteArray dataList)
{

    PortStruct target;
    foreach (const BasePort *port , m_portList)
    {
         if((port->portParam().type() == "UART" && port->portParam().name() == "SWKNX"))
         {
             target = port->portParam();
         }
    }


    writeKNXCtrlCmd *mm = new writeKNXCtrlCmd();

    mm->setGroupAddress(address);
    mm->setKnxLen(len);
    mm->setDataList(dataList);


    QSharedPointer<BaseCmd> sharedSetControlPointCmd(mm);

     /*SavePointXml *savePointXml =SavePointXml::getInstance();

     savePointXml->SavePointData(address,value);
     QString stata="Write-RS485";
     savePointXml->JoinSystemList(address,value,stata);*/

    sendCmd(target,sharedSetControlPointCmd);

}
void SWKNXDevice::writeC3()
{

    PortStruct target;

    foreach (const BasePort *port , m_portList)
    {

         if((port->portParam().type() == "UART" && port->portParam().name() == "SWKNX"))
         {
             target = port->portParam();
         }
    }

    QByteArray data;
    data.append(0xC3);

    emit sendDataSignal(target,data);

}

void SWKNXDevice::readKNXCtrlCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    quint16 fbAddress=0;
    Q_UNUSED(source);
    qDebug()<<"~~~~~~~~~~~~~~SWKNXDevice::readKNXCtrlCmdHandle";
    writeC3();
    readKNXCtrlCmd * _readKNXCtrlCmd = qobject_cast<readKNXCtrlCmd*>(sharedCmd.data());

   // System *system = System::getInstance();
   // system->setKNXStatus(_ackKNXStatusCmd->getKNXStatus());

   ControlKNXFunc *knxControlFunc = new ControlKNXFunc();
    SWKNXDataStruct sourceKNX;
   sourceKNX.setGroupAddress(_readKNXCtrlCmd->groupAddress());
    sourceKNX.setKnxLen(_readKNXCtrlCmd->knxLen());
    sourceKNX.setDataList(_readKNXCtrlCmd->dataList());
    qDebug()<<"groupaddress-"<<sourceKNX.groupAddress();

    qDebug()<<"knxlen-"<<sourceKNX.knxLen();
    qDebug()<<"dataList-"<<DataTypeConver::formatString(sourceKNX.dataList());

    SWKNXListXml *swKNXListxml = SWKNXListXml::getInstance();
    QMap<SWKNXDataStruct, QList<ControlPointStruct> > map = swKNXListxml->sceneMap();
    QMap<SWKNXDataStruct,QList<ControlPointStruct> >::iterator it;
    for(it=map.begin();it!=map.end();++it)
    {
        if(sourceKNX == it.key())
        {
              fbAddress=  it.key().fbAddress();
              qDebug()<<"fbAddress "<<fbAddress;
        }
    }

    if(fbAddress > 0)
    writeFB(fbAddress,_readKNXCtrlCmd->knxLen(),_readKNXCtrlCmd->dataList());

    QList<SWKNXDataStruct> sourceKNXList;
    sourceKNXList.append(sourceKNX);
    knxControlFunc->setSourceDevice(this->name());
    knxControlFunc->setSourceKNXList(sourceKNXList);
    QSharedPointer<BaseFunc> sharedPointControlFunc(knxControlFunc);
    emit transferFuncSignal(sharedPointControlFunc);
}

void SWKNXDevice:: ackKNXStatusCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    Q_UNUSED(source);
    qDebug()<<"~~~~~~~~~~~~~~SWKNXDevice::ackKNXStatusCmdHandle11";




    writeC3();
    ackKNXStatusCmd * _ackKNXStatusCmd = qobject_cast<ackKNXStatusCmd*>(sharedCmd.data());
    System *system = System::getInstance();
    system->setKNXStatus(_ackKNXStatusCmd->getKNXStatus());
    getStatusTimer->stop();

}

void SWKNXDevice::ackKNXMacCmdHandle(PortStruct source, QSharedPointer<BaseCmd> sharedCmd)
{
    qDebug()<<"~~~~~~~~~~~~~~SWKNXDevice::ackKNXMacCmdHandle";
    writeC3();
    ackKNXMacCmd *_ackKNXMacCmd = qobject_cast<ackKNXMacCmd*>(sharedCmd.data());

  //  UpperSearchResponseCmd *upperSearchResponseCmd = new UpperSearchResponseCmd();
  //  upperSearchResponseCmd->setKNXMac(_ackKNXMacCmd->getKNXMac());

    System *system = System::getInstance();
    system->setKNXMac(_ackKNXMacCmd->getKNXMac());

    getMacTimer->stop();

}

void SWKNXDevice::getStatusSlot()
{

      qDebug()<<"SWKNXDevice::getStatusSlot()";

    getKNXStatusCmd * mm = new getKNXStatusCmd();
    QSharedPointer<BaseCmd> sharedSyncCmd(mm);

    PortStruct target;

    foreach (const BasePort *port , m_portList)
    {
         if((port->portParam().type() == "UART" && port->portParam().name() == "SWKNX"))
         {
             target = port->portParam();
         }
    }
 //   this->sendCmd(target,sharedSyncCmd);
}


void SWKNXDevice::getMacSlot()
{
    qDebug()<<"SWKNXDevice::getMacSlot()";

    getKNXMacCmd *mm = new getKNXMacCmd();
     QSharedPointer<BaseCmd> sharedSyncCmd(mm);

    PortStruct target;
   // qDebug()<<"getMacSlot m_portList-"<<m_portList.size();
    foreach (const BasePort *port , m_portList)
    {
         if((port->portParam().type() == "UART" && port->portParam().name() == "SWKNX"))
         {
             target = port->portParam();
         }
    }
 //  this->sendCmd(target,sharedSyncCmd);
}

void SWKNXDevice::heartbeatSlot()
{
    CtrlSWKNXProgramLed *ctrlLedCmd = new CtrlSWKNXProgramLed();
    if(ss==0)
        ss=1;
    else
        ss=0;
    ctrlLedCmd->setState(ss);
    QSharedPointer<BaseCmd> sharedSyncCmd(ctrlLedCmd);

    PortStruct target;
    foreach (const BasePort *port , m_portList)
    {
         if((port->portParam().type() == "UART" && port->portParam().name() == "SWKNX"))
         {
             target = port->portParam();
         }
    }
    this->sendCmd(target,sharedSyncCmd);
}

void SWKNXDevice::controlKNXFuncHandle(QSharedPointer<BaseFunc> sharedFunc)
{
    ControlKNXFunc *knxControlFunc = qobject_cast<ControlKNXFunc*>(sharedFunc.data());
    QList<SWKNXDataStruct> controlKNXList;

    qDebug()<<"[SWKNXDevice::controlKNXFuncHandle]"<<knxControlFunc->sourceDevice()<<" "<<this->name();
    if(knxControlFunc->sourceDevice() == this->name())
        return;
   controlKNXList.append(knxControlFunc->sourceKNXList());
   qDebug()<<"[SWKNXDevice::controlKNXFuncHandle] controlKNXList.size="<<controlKNXList.size();


   PortStruct target;
   foreach (const BasePort *port , m_portList)
   {
        if((port->portParam().type() == "UART" && port->portParam().name() == "SWKNX"))
        {
            target = port->portParam();
        }
   }

   for(int i=0; i<controlKNXList.size(); i++)
   {

       SWKNXDataStruct controlKNX = controlKNXList.at(i);
       quint16 gropAddress = controlKNX.groupAddress();
       int knxlen = controlKNX.knxLen();
       QByteArray knxDataList = controlKNX.dataList();
       quint64 getDelayTime=controlKNX.delayTime();




           if(getDelayTime==0)
           {
               qDebug()<<"Time is zero now--"<<gropAddress<<"  "<<knxlen;

               writeKNXCtrlCmd *mm = new writeKNXCtrlCmd();

               mm->setGroupAddress(gropAddress);
               mm->setKnxLen(knxlen);
               mm->setDataList(knxDataList);


               QSharedPointer<BaseCmd> sharedSetControlPointCmd(mm);

                /*SavePointXml *savePointXml =SavePointXml::getInstance();

                savePointXml->SavePointData(address,value);
                QString stata="Write-RS485";
                savePointXml->JoinSystemList(address,value,stata);*/

               sendCmd(target,sharedSetControlPointCmd);


           }else
           {
               DelaySendList.append(controlKNX);
             //  qDebug()<<"[PointDevice.cpp:controlPointFuncHandle]joinDelayTime---"<<controlPoint.address()<<"  "<<controlPoint.value();
             //  controlPoint.setPortStruct(target);
            //   SceneListXml *sceneListXml = SceneListXml::getInstance();
           //  sceneListXml->joinDelayTimeList(controlPoint);
           }


   }

}

void SWKNXDevice::DelaySendSlot()
{
   // qDebug()<<"DelaySendSlot hello";
    static int count=0;
    count++;
    int i;

    System *system = System::getInstance();
    if(system->getGlobalStatus() == 1)
    {
        restartTimer();
        system->setGlobalStatus(0);
    }
  //  if(DelaySendList.size() > 0)
 //       qDebug()<<"[PointDevice::DelaySendSlot] DelaySendList.size()=="<<DelaySendList.size();
    for(i=0;i<DelaySendList.size();i++)
    {

        SWKNXDataStruct Struct=DelaySendList.at(i);

        quint64 structDelayTime=Struct.delayTime();
        // qDebug()<<"DelaySendSlot i="<<i<<" "<<Struct.address()<<" "<<Struct.value()<<" "<<structDelayTime;



        if(structDelayTime>0)
        {
            Struct.setDelayTime(structDelayTime-1);
            DelaySendList.replace(i,Struct);
        }
        else
        {
            int gropAddress = Struct.groupAddress();
            int knxlen = Struct.knxLen();
            QByteArray knxDataList = Struct.dataList();

            writeKNXCtrlCmd *nn = new writeKNXCtrlCmd();
            nn->setGroupAddress(gropAddress);
            nn->setKnxLen(knxlen);
            nn->setDataList(knxDataList);

            QSharedPointer<BaseCmd> sharedSetControlPointCmd(nn);


             /*SavePointXml *savePointXml =SavePointXml::getInstance();

             savePointXml->SavePointData(address,value);
             QString stata="Write-RS485";
             savePointXml->JoinSystemList(address,value,stata);*/
            if(DelaySendList.size()!=1)
            {
            DelaySendList.removeAt(i);
            }else
            {
               qDebug()<<"clean list now--------------------------";
                DelaySendList.clear();

            }

            PortStruct target;
            foreach (const BasePort *port , m_portList)
            {
                 if((port->portParam().type() == "UART" && port->portParam().name() == "SWKNX"))
                 {
                     target = port->portParam();
                 }
            }

            sendCmd(target,sharedSetControlPointCmd);

        }

    }

}

void SWKNXDevice::restartTimer()
{
    getMacTimer->setInterval(5*1000);
    getMacTimer ->start();

    getStatusTimer->setInterval(8*1000);
  getStatusTimer ->start();

}




